package com.redstar.interesting.common.starter.intercepter;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;

import java.sql.Statement;
import java.util.Properties;

/**
 * <a href = "https://mybatis.org/mybatis-3/zh/configuration.html#plugins"><h3>Mybatis中文文档</h3></a>
 * <hr>
 * <p>mybatis给
 * {@link org.apache.ibatis.executor.Executor}、
 * {@link org.apache.ibatis.executor.statement.StatementHandler}、
 * {@link org.apache.ibatis.executor.resultset.ResultSetHandler}、
 * {@link org.apache.ibatis.executor.parameter.ParameterHandler}提供了拦截器功能
 * </p>
 * <p>
 * {@link org.apache.ibatis.executor.Executor}提供了增删改查的接口<br>
 * {@link org.apache.ibatis.executor.statement.StatementHandler}负责处理 mybatis 与jdbc之间 statement 的交互<br>
 * {@link org.apache.ibatis.executor.resultset.ResultSetHandler}负责处理statement执行后产生的结果集，生成结果集列表<br>
 * {@link org.apache.ibatis.executor.parameter.ParameterHandler}是mybatis 实现 SQL入参设置的对象<br>
 * </p>
 * <p>
 *     拦截器采用了责任链模式，把请求发送者和请求处理者分开，各司其职<br>
 *     mybatis拦截器可以对{@link org.apache.ibatis.executor.Executor}、{@link org.apache.ibatis.executor.statement.StatementHandler}、
 *     {@link org.apache.ibatis.executor.resultset.ResultSetHandler}、{@link org.apache.ibatis.executor.parameter.ParameterHandler}
 *     中的方法进行拦截。只需在{@link org.apache.ibatis.plugin.Signature}注解中标明拦截的是哪个类的哪个方法。<br>
 * </p>
 *
 * @author lihongxing
 */
@Slf4j
@Component
@Intercepts({
        @Signature(
                type = Executor.class,
                method = "query",
                args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}
        ),
        @Signature(
                type = Executor.class,
                method = "query",
                args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}
        ),
        @Signature(
                type = Executor.class,
                method = "update",
                args = {MappedStatement.class, Object.class}
        )
})
public class RouteDataSourceInterceptor implements Interceptor {

    private Properties properties = new Properties();


    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        log.info("自定义Mybatis拦截器-setProperties");
        this.properties = properties;
    }
}
